Introduction
Trimesh is a powerful Python library for loading, processing, and analyzing triangular meshes. It provides an extensive set of tools for working with 3D geometry, making it ideal for computer graphics, 3D printing, robotics, and scientific visualization.
💡 Key Features: Trimesh supports various file formats (STL, OBJ, PLY, GLTF), provides mesh analysis tools, boolean operations, ray tracing, and much more.
Installation
Install Trimesh using pip:
# Basic installation
pip install trimesh
# With additional dependencies for full functionality
pip install trimesh[easy]
Getting Started
1. Loading a Mesh
import trimesh
# Load a mesh from file
mesh = trimesh.load_mesh('model.stl')
# Or create a simple primitive
sphere = trimesh.primitives.Sphere(radius=1.0)
cube = trimesh.primitives.Box(extents=[2, 2, 2])
2. Basic Mesh Properties
# Access mesh properties
print(f"Vertices: {len(mesh.vertices)}")
print(f"Faces: {len(mesh.faces)}")
print(f"Volume: {mesh.volume}")
print(f"Surface Area: {mesh.area}")
print(f"Center of Mass: {mesh.center_mass}")
print(f"Bounding Box: {mesh.bounds}")
3. Mesh Visualization
# Show the mesh in a window
mesh.show()
# Or export as image
scene = mesh.scene()
png = scene.save_image(resolution=[1920, 1080])
Common Operations
Transformations
Translate, rotate, and scale meshes easily
Boolean Operations
Union, difference, and intersection of meshes
Mesh Repair
Fix holes, remove duplicates, and merge vertices
Ray Tracing
Cast rays and detect intersections
Transformations
import numpy as np
# Translation
mesh.apply_translation([1, 0, 0])
# Rotation (45 degrees around Z-axis)
rotation_matrix = trimesh.transformations.rotation_matrix(
np.radians(45), [0, 0, 1]
)
mesh.apply_transform(rotation_matrix)
# Scaling
mesh.apply_scale(2.0) # Uniform scaling
mesh.apply_scale([2, 1, 1]) # Non-uniform scaling
Boolean Operations
# Create two meshes
sphere1 = trimesh.primitives.Sphere(radius=1.0)
sphere2 = trimesh.primitives.Sphere(radius=0.8)
sphere2.apply_translation([0.5, 0, 0])
# Union (combine meshes)
union = sphere1.union(sphere2)
# Difference (subtract one from another)
difference = sphere1.difference(sphere2)
# Intersection
intersection = sphere1.intersection(sphere2)
Mesh Analysis
# Check if mesh is watertight (closed)
print(f"Watertight: {mesh.is_watertight}")
# Check if mesh is convex
print(f"Convex: {mesh.is_convex}")
# Get mesh quality metrics
print(f"Euler Number: {mesh.euler_number}")
# Find holes in the mesh
holes = mesh.faces_sparse()
# Calculate inertia tensor
inertia = mesh.moment_inertia
Advanced Features
Ray Casting
# Cast rays at the mesh
ray_origins = [[0, 0, -5]]
ray_directions = [[0, 0, 1]]
# Find intersection points
locations, index_ray, index_tri = mesh.ray.intersects_location(
ray_origins=ray_origins,
ray_directions=ray_directions
)
print(f"Intersection points: {locations}")
Mesh Slicing
# Slice mesh with a plane
plane_origin = [0, 0, 0]
plane_normal = [0, 0, 1]
slice_2d = mesh.section(
plane_origin=plane_origin,
plane_normal=plane_normal
)
# Get 2D path from slice
if slice_2d is not None:
path, to_3D = slice_2d.to_planar()
path.show()
Convex Hull
# Create convex hull of point cloud or mesh
convex_hull = mesh.convex_hull
# Or from points directly
points = np.random.random((100, 3))
hull = trimesh.convex.convex_hull(points)
Voxelization
# Convert mesh to voxel representation
voxels = mesh.voxelized(pitch=0.1)
# Convert voxels back to mesh
voxel_mesh = voxels.as_boxes()
voxel_mesh.show()
Practical Examples
Example 1: Create a Hollow Sphere
import trimesh
# Create outer and inner spheres
outer = trimesh.primitives.Sphere(radius=2.0)
inner = trimesh.primitives.Sphere(radius=1.8)
# Subtract inner from outer
hollow_sphere = outer.difference(inner)
# Save result
hollow_sphere.export('hollow_sphere.stl')
hollow_sphere.show()
Example 2: Mesh Repair and Cleanup
# Load potentially broken mesh
mesh = trimesh.load('broken_model.stl')
# Remove duplicate vertices
mesh.merge_vertices()
# Remove degenerate faces
mesh.remove_degenerate_faces()
# Fill holes
mesh.fill_holes()
# Fix normals
mesh.fix_normals()
print(f"Mesh is now watertight: {mesh.is_watertight}")
mesh.export('repaired_model.stl')
Example 3: Point Cloud to Mesh
import numpy as np
# Generate point cloud (e.g., from scanning)
points = np.random.random((1000, 3)) * 10
# Create point cloud object
cloud = trimesh.PointCloud(points)
# Convert to mesh using convex hull
mesh = cloud.convex_hull
# Or use ball pivoting algorithm (requires additional setup)
# mesh = trimesh.points.ball_pivot(points, radius=0.5)
mesh.show()
Export Formats
Trimesh supports numerous file formats for import and export:
# Export to different formats
mesh.export('output.stl') # STL format
mesh.export('output.obj') # Wavefront OBJ
mesh.export('output.ply') # PLY format
mesh.export('output.off') # OFF format
mesh.export('output.glb') # GLTF/GLB format
# Export with specific settings
mesh.export('output.stl', file_type='stl_ascii')
⚠️ Note: Some formats preserve more information than others. GLB/GLTF formats support colors and textures, while STL only stores geometry.
Tips and Best Practices
- Always check if a mesh is watertight before performing boolean operations
- Use mesh repair functions when loading meshes from external sources
- For large meshes, consider simplification using mesh.simplify_quadric_decimation()
- When working with multiple meshes, keep track of their coordinate systems
- Use mesh.bounds to understand the spatial extent of your geometry
- For better performance, consider using mesh caching: mesh.cache.clear() to manage memory